package main;

import java.io.IOException;
import java.net.InetAddress;
import java.net.Socket;

public class Controller {
	boolean gameInProgress;
	ConnectionListener connectionListener;
	ConnectToGame ctg = null;
	GameFlow gf;
	View view;
	private static final int DEST_PORT = 43211;
	
	/**
	 * Create lisener & gameFlow objects
	 * @param view
	 * @throws IOException
	 */
	public Controller(View view) throws IOException{
		this.view = view;
		//connectionListener = new ConnectionListener(this);
		gf = new GameFlow(this);
		new Thread(connectionListener).start();
		gameInProgress = false;
	}
	
	/**
	 * If opponent wants to play - check that user not in game and wants to play
	 * set up labels and buttons in view
	 * 
	 * @param socket
	 * @throws IOException
	 */
	public void gameRequestFromOpponent(Socket socket) throws IOException{
		if (!gameInProgress && view.askForAcceptance(socket.getInetAddress())){
			ctg = new ConnectToGame(socket,this);
			gameInProgress = true;
			view.toggleButtons(true);
			view.setConnectButton(false);
		} else {
			//if game invitation is declined - close socket
			socket.close();
		}
	}
	
	/**
	 * Attempt to connect to opponent
	 * @param ip
	 * @throws IOException
	 */
	public void connectToGame(InetAddress ip) throws IOException {
		ctg = new ConnectToGame(ip, DEST_PORT, this);
		gameInProgress = true;
	}
	
	/**
	 * Pass choice on to gameFlow and connectToGame instances
	 * @param c
	 */
	public void sendChoice(Choice c) {
		ctg.sendChoice(c);
		gf.userChoice(c);
	}
	
	/**
	 * Called by gameFlow when round is done. Pass new data on to view instance.
	 * @param msg
	 * @param userScore
	 * @param opponentScore
	 */
	public void roundFinished(String msg, int userScore, int opponentScore) {
		view.updateScore(msg, userScore, opponentScore);
	}
	
	/**
	 * Receive opponents choice. Update view and gameFlow instances
	 * @param c
	 */
	public void  receiveChoice(Choice c) {
		gf.opponentChoice(c);
		view.gameMessage("Opponent is waiting for your choice...");
	} 
	
	/**
	 * Connection lost - reset gameFlow and labels in view.
	 */
	public void lostConnectionToOpponent(){
		gf.reset();
		view.errorMessage("Your opponent disconnected from game");
		gameInProgress = false;
		view.resetLabels();
	}
	
	/**
	 * User have chosen to disconnect - reset gameFlow and labels in view.
	 */
	public void disconnect() {
		gf.reset();
		ctg.disconnect();
		view.resetLabels();
		gameInProgress = false;
	}
	
}
